package chagine.mdt.feign;

import chagine.core.Env;
import chagine.core.ErrorCode;
import chagine.core.exception.SeeingException;
import chagine.core.restful.util.TResponse;
import chagine.core.util.*;
import chagine.mdt.feign.vo.*;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Response;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * create by wba on  2020/2/9
 * qq:43585061
 */
@FeignClient(ServiceName.RESOURCE_SERVICE)
public interface ResourceClient {

    @RequestMapping(value = "/file/get_file", method = RequestMethod.GET)
    TResponse<FileVo> getFile(@RequestParam(value = "file_id", required = false) Long fileId, @RequestHeader(name = Env.HEAD_TENANT_KEY) Long tenantId);

    /**
     * 下载资源文件
     */
    @GetMapping(value = "/file/get_file_byte_by_path")
    Response getFileByteByPath(@RequestParam(value = "path", required = false) String path);

    /**
     * 下载资源文件
     */
    default DownFileVo detailGetFileByteByPath(String path) throws SeeingException {
        Response res = getFileByteByPath(path);
        int status = res.status();
        if (status != HttpStatus.OK.value()) {
            // 请求失败
            try {
                Response.Body body = res.body();
                InputStream inputStream = body.asInputStream();
                String json = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
                ObjectMapper objectMapper = new ObjectMapper();
                TResponse tResponse = objectMapper.readValue(json, new TypeReference<TResponse<Object>>() {
                });
                String message = tResponse.getMessage();
                throw new SeeingException(ErrorCode.BUSINESS_EXCEPTION, message);
            } catch (IOException e) {
                throw new SeeingException(ErrorCode.BUSINESS_EXCEPTION, e.getMessage());
            }
        } else {
            try {
                Response.Body body = res.body();
                InputStream inputStream = body.asInputStream();
                String fileName = ResponseUtil.getHeaderFileName(res);
                fileName = URLDecoder.decode(fileName, "UTF-8");
                DownFileVo fileVo = new DownFileVo();
                fileVo.setFileName(fileName);
                fileVo.setInputStream(inputStream);
                return fileVo;
            } catch (IOException e) {
                throw new SeeingException(ErrorCode.BUSINESS_EXCEPTION, e.getMessage());
            }
        }
    }


    /**
     * 服务间文件上传
     *
     * @param file     待上传的文件
     * @param tenantId 租户号
     * @param userId   用户ID
     */
    @PostMapping(value = "/feign/file/upload_file",
            consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
            produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
    TResponse<FileVo> uploadFile(@RequestPart(value = "file") MultipartFile file,
                                 @RequestHeader(value = Env.HEAD_TENANT_KEY) Long tenantId,
                                 @RequestHeader(value = Env.HEAD_USERID_KEY) Long userId);


    /**
     * 腾讯xinge推送
     */
    @RequestMapping(value = "/xinge/push", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    TResponse<YesNoVo> xingePush(@RequestBody FXingeMessageVo fXingeMessageVo, @RequestHeader(name = Env.HEAD_TENANT_KEY, required = false) Long tenantId);


    /**
     * 按账号发送透传消息，发送透传消息
     *
     * @throws SeeingException
     */
    default void detailXingePushAppMessage(Integer bizType, Integer messageType, String title, String content, List<String> accountList, Object customContentObj, Long tenaId) {
        FXingeMessageVo messageVo = new FXingeMessageVo();
        messageVo.setMessageType(messageType);
        messageVo.setTitle(StringUtils.isBlank(title) ? "" : title);
        messageVo.setContent(StringUtils.isBlank(content) ? "" : content);
        messageVo.setAccountList(accountList);
        messageVo.setBizType(bizType);
        if (customContentObj != null) {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                messageVo.setCustomContent(objectMapper.writeValueAsString(customContentObj));
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
        }
        TResponse<YesNoVo> response = xingePush(messageVo, tenaId);
        YesNoVo value =  FeignUtil.getResponseData(response);
        Assert.error(value.getRst() != 1, ErrorCode.BUSINESS_EXCEPTION, value.getMsg());
    }


    /**
     * @param bizId   业务标识id
     * @param bizType 7-产时预警
     * @return
     */
    @RequestMapping(value = "/trtc/create_room_no", method = RequestMethod.POST)
    TResponse<Long> createRoomNo(@RequestParam(value = "biz_id", required = false) Long bizId, @RequestParam(value = "biz_type", required = false) Integer bizType, @RequestHeader(name = Env.HEAD_TENANT_KEY, required = false) Long tenantId);

    default Long detailCreateRoomNo(Long bizId, Long tenaId) {
        TResponse<Long> response = createRoomNo(bizId,7, tenaId);
        Long roomNo =  FeignUtil.getResponseData(response);
        return roomNo;
    }

    @RequestMapping(value = "/trtc/dismissRoom", method = RequestMethod.POST)
    TResponse<YesNoVo> dismissRoom(@RequestParam(value = "room_id", required = false) Long roomId, @RequestHeader(name = Env.HEAD_TENANT_KEY, required = false) Long tenantId);

    /**
     * 按账号发送透传消息，发送透传消息
     *
     * @throws SeeingException
     */
    default void detailDismissRoom(Long roomId, Long tenaId) {
        TResponse<YesNoVo> response = dismissRoom(roomId, tenaId);
        YesNoVo value =  FeignUtil.getResponseData(response);
        Assert.error(value.getRst() != 1, ErrorCode.BUSINESS_EXCEPTION, value.getMsg());
    }



    @RequestMapping(value = "/trtc/get_video_record_list", method = RequestMethod.GET)
    TResponse<List<FTRTCVideoRecordVo>> getVideoRecordList(@RequestParam(value = "biz_id", required = false) Long bizId, @RequestHeader(name = Env.HEAD_TENANT_KEY) Long tenantId);

    /**
     * 视频回调记录
     *
     * @param bizId    订单号
     * @param tenantId 租户号
     */
    default List<FTRTCVideoRecordVo> detailVideoRecordList(Long bizId, Long tenantId) {
        // 调用视频
        TResponse<List<FTRTCVideoRecordVo>> response = getVideoRecordList(bizId, tenantId);
        if (response.isSuccess()) {
            return response.getData();
        }
        return null;
    }


    /**
     * 创建群组
     */
    @RequestMapping(value = "/tim/create_group", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    TResponse<FTimResponseVo> createGroup(@RequestBody FTimRequestVo feignTimVo, @RequestHeader(name = Env.HEAD_TENANT_KEY, required = false) Long tenantId);

    default FTimResponseVo detailCreateGroup(String groupName, Integer maxMemberCount, Long tenaId) throws SeeingException {
        FTimRequestVo requestVo = new FTimRequestVo();
        requestVo.setGroupName(groupName);
        requestVo.setMaxMemberCount(maxMemberCount);
        TResponse<FTimResponseVo> response = createGroup(requestVo, tenaId);
        return FeignUtil.getResponseData(response);
    }


    /**
     * 解散群
     */
    @RequestMapping(value = "/tim/destroy_group", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    TResponse<FTimResponseVo> destroyGroup(@RequestBody FTimRequestVo feignTimVo, @RequestHeader(name = Env.HEAD_TENANT_KEY, required = false) Long tenantId);

    default FTimResponseVo detailDestroyGroup(String groupId, Long tenaId) throws SeeingException {
        FTimRequestVo requestVo = new FTimRequestVo();
        requestVo.setGroupId(groupId);
        TResponse<FTimResponseVo> response = destroyGroup(requestVo, tenaId);
        return FeignUtil.getResponseData(response);
    }


    /**
     * 增加群成员
     */
    @RequestMapping(value = "/tim/add_group_member", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
    TResponse<FTimResponseVo> addGroupember(@RequestBody FTimRequestVo feignTimVo, @RequestHeader(name = Env.HEAD_TENANT_KEY, required = false) Long tenantId);

    default FTimResponseVo detailAddGroupember(String groupId, List<String> addUserList, Long tenaId) throws SeeingException {
        FTimRequestVo requestVo = new FTimRequestVo();
        requestVo.setGroupId(groupId);
        requestVo.setMemberList(addUserList);
        TResponse<FTimResponseVo> response = addGroupember(requestVo, tenaId);
        return FeignUtil.getResponseData(response);
    }

}
